#include <QtMatrix4x4Manager.h>


QtMatrix4x4Manager::QtMatrix4x4Manager(QObject *parent /*= 0*/ ) : QtAbstractPropertyManager(parent)
{
    m_doublePropertyManager = new QtDoublePropertyManager(this);
    connect(m_doublePropertyManager, SIGNAL(valueChanged(QtProperty*,double)),
                this, SLOT(slotDoubleChanged(QtProperty*,double)));

}

QtMatrix4x4Manager::~QtMatrix4x4Manager()
{

}

QMatrix4x4 QtMatrix4x4Manager::value(QtProperty *property_ptr)
{
    return m_propertyPtrToMatrix.value(property_ptr, QMatrix4x4());
}

QtDoublePropertyManager *QtMatrix4x4Manager::subDoublePropertyManager() const
{
    return m_doublePropertyManager;
}

void QtMatrix4x4Manager::slotDoubleChanged(QtProperty *property, double value)
{
    if (QtProperty *xprop = m_XToproperty.value(property, 0)) {
        QMatrix4x4 p = m_propertyPtrToMatrix[xprop];
        p(0,3) = value;
        setValue(xprop, p);
    } else if (QtProperty *yprop = m_YToproperty.value(property, 0)) {
        QMatrix4x4 p = m_propertyPtrToMatrix[yprop];
        p(1,3) = value;
        setValue(yprop, p);
    } else if (QtProperty *zprop = m_ZToproperty.value(property, 0)) {
        QMatrix4x4 p = m_propertyPtrToMatrix[zprop];
        p(2,3) = value;
        setValue(zprop, p);
    } else if (QtProperty *rxprop = m_RXToproperty.value(property, 0)) {
        QMatrix4x4 p = m_propertyPtrToMatrix[rxprop];
        p(0,2) = value;
        setValue(rxprop, p);
    } else if (QtProperty *ryprop = m_RYToproperty.value(property, 0)) {
        QMatrix4x4 p = m_propertyPtrToMatrix[ryprop];
        p(1,2) = value;
        setValue(ryprop, p);
    } else if (QtProperty *rzprop = m_RZToproperty.value(property, 0)) {
        QMatrix4x4 p = m_propertyPtrToMatrix[rzprop];
        p(2,2) = value;
        setValue(rzprop, p);
    } else if (QtProperty *sxprop = m_SXToproperty.value(property, 0)) {
        QMatrix4x4 p = m_propertyPtrToMatrix[sxprop];
        p(0,1) = value;
        setValue(sxprop, p);
    } else if (QtProperty *syprop = m_SYToproperty.value(property, 0)) {
        QMatrix4x4 p = m_propertyPtrToMatrix[syprop];
        p(1,1) = value;
        setValue(syprop, p);
    } else if (QtProperty *szprop = m_SZToproperty.value(property, 0)) {
        QMatrix4x4 p = m_propertyPtrToMatrix[szprop];
        p(2,1) = value;
        setValue(szprop, p);
    } else if (QtProperty *stepProp = m_SingleStepToproperty.value(property, 0)) {
        m_doublePropertyManager->setSingleStep(m_propertyToX[stepProp],value);
        m_doublePropertyManager->setSingleStep(m_propertyToY[stepProp],value);
        m_doublePropertyManager->setSingleStep(m_propertyToZ[stepProp],value);

        m_doublePropertyManager->setSingleStep(m_propertyToRX[stepProp],value);
        m_doublePropertyManager->setSingleStep(m_propertyToRY[stepProp],value);
        m_doublePropertyManager->setSingleStep(m_propertyToRZ[stepProp],value);

        m_doublePropertyManager->setSingleStep(m_propertyToSX[stepProp],value);
        m_doublePropertyManager->setSingleStep(m_propertyToSY[stepProp],value);
        m_doublePropertyManager->setSingleStep(m_propertyToSZ[stepProp],value);

    }
}

void QtMatrix4x4Manager::setValue(QtProperty *property_ptr, const QMatrix4x4 &value_matrix)
{
    const QMap<const QtProperty *, QMatrix4x4>::iterator it = m_propertyPtrToMatrix.find(property_ptr);
    if (it == m_propertyPtrToMatrix.end())
        return;

    if (it.value() == value_matrix)
        return;

    it.value() = value_matrix;
    m_doublePropertyManager->setValue(m_propertyToX[property_ptr], value_matrix(0,3));
    m_doublePropertyManager->setValue(m_propertyToY[property_ptr], value_matrix(1,3));
    m_doublePropertyManager->setValue(m_propertyToZ[property_ptr], value_matrix(2,3));

    m_doublePropertyManager->setValue(m_propertyToRX[property_ptr], value_matrix(0,2));
    m_doublePropertyManager->setValue(m_propertyToRY[property_ptr], value_matrix(1,2));
    m_doublePropertyManager->setValue(m_propertyToRZ[property_ptr], value_matrix(2,2));

    m_doublePropertyManager->setValue(m_propertyToSX[property_ptr], value_matrix(0,1));
    m_doublePropertyManager->setValue(m_propertyToSY[property_ptr], value_matrix(1,1));
    m_doublePropertyManager->setValue(m_propertyToSZ[property_ptr], value_matrix(2,1));

    emit propertyChanged(property_ptr);
    emit valueChanged(property_ptr, value_matrix);
}

void QtMatrix4x4Manager::initializeProperty(QtProperty *property)
{
    m_propertyPtrToMatrix[property] = QMatrix4x4();

    QtProperty *singleStepProp = m_doublePropertyManager->addProperty();
    singleStepProp->setPropertyName(tr("SingleStep"));
    m_doublePropertyManager->setValue(singleStepProp, 1);
    m_propertyToSingleStep[property] = singleStepProp;
    m_SingleStepToproperty[singleStepProp] = property;
    property->addSubProperty(singleStepProp);


    QtProperty *xProp = m_doublePropertyManager->addProperty();
    xProp->setPropertyName(tr("X"));
    m_doublePropertyManager->setValue(xProp, 0);
    m_propertyToX[property] = xProp;
    m_XToproperty[xProp] = property;
    property->addSubProperty(xProp);

    QtProperty *yProp = m_doublePropertyManager->addProperty();
    yProp->setPropertyName(tr("Y"));
    m_doublePropertyManager->setValue(yProp, 0);
    m_propertyToY[property] = yProp;
    m_YToproperty[yProp] = property;
    property->addSubProperty(yProp);

    QtProperty *zProp = m_doublePropertyManager->addProperty();
    zProp->setPropertyName(tr("Z"));
    m_doublePropertyManager->setValue(zProp, 0);
    m_propertyToZ[property] = zProp;
    m_ZToproperty[zProp] = property;
    property->addSubProperty(zProp);

    QtProperty *rxProp = m_doublePropertyManager->addProperty();
    rxProp->setPropertyName(tr("RX"));
    m_doublePropertyManager->setValue(rxProp, 0);
    m_propertyToRX[property] = rxProp;
    m_RXToproperty[rxProp] = property;
    property->addSubProperty(rxProp);

    QtProperty *ryProp = m_doublePropertyManager->addProperty();
    ryProp->setPropertyName(tr("RY"));
    m_doublePropertyManager->setValue(ryProp, 0);
    m_propertyToRY[property] = ryProp;
    m_RYToproperty[ryProp] = property;
    property->addSubProperty(ryProp);

    QtProperty *rzProp = m_doublePropertyManager->addProperty();
    rzProp->setPropertyName(tr("RZ"));
    m_doublePropertyManager->setValue(rzProp, 0);
    m_propertyToRZ[property] = rzProp;
    m_RZToproperty[rzProp] = property;
    property->addSubProperty(rzProp);

    QtProperty *sxProp = m_doublePropertyManager->addProperty();
    sxProp->setPropertyName(tr("SX"));
    m_doublePropertyManager->setValue(sxProp, 1);
    m_propertyToSX[property] = sxProp;
    m_SXToproperty[sxProp] = property;
    property->addSubProperty(sxProp);

    QtProperty *syProp = m_doublePropertyManager->addProperty();
    syProp->setPropertyName(tr("SY"));
    m_doublePropertyManager->setValue(syProp, 1);
    m_propertyToSY[property] = syProp;
    m_SYToproperty[syProp] = property;
    property->addSubProperty(syProp);

    QtProperty *szProp = m_doublePropertyManager->addProperty();
    szProp->setPropertyName(tr("SZ"));
    m_doublePropertyManager->setValue(szProp, 1);
    m_propertyToSZ[property] = szProp;
    m_SZToproperty[szProp] = property;
    property->addSubProperty(szProp);

    m_doublePropertyManager->setDecimals(xProp, 6);
    m_doublePropertyManager->setDecimals(yProp, 6);
    m_doublePropertyManager->setDecimals(zProp, 6);

    m_doublePropertyManager->setDecimals(rxProp, 6);
    m_doublePropertyManager->setDecimals(ryProp, 6);
    m_doublePropertyManager->setDecimals(rzProp, 6);

    m_doublePropertyManager->setDecimals(sxProp, 6);
    m_doublePropertyManager->setDecimals(syProp, 6);
    m_doublePropertyManager->setDecimals(szProp, 6);

}

QString QtMatrix4x4Manager::valueText(const QtProperty *property) const
{
    const QMap<const QtProperty *, QMatrix4x4>::const_iterator it = m_propertyPtrToMatrix.constFind(property);
    if (it == m_propertyPtrToMatrix.constEnd())
        return QString();
    const QMatrix4x4 v = it.value();
    //return tr("(%1, %2)").arg(QString::number(v.x())).arg(QString::number(v.y()));
    return QString("Matrix value");
}

#include "moc_QtMatrix4x4Manager.cxx"

